package com.zisu.a996.stream;

/**
 * @Author: 蔡翔
 * @Date: 2019/11/22 9:48
 * @Version 1.0
 */

import com.alibaba.fastjson.JSON;
import com.zisu.a996.lambda.cart.CartService;
import com.zisu.a996.lambda.cart.Sku;
import com.zisu.a996.lambda.cart.SkuCategory;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


/**
 * 原始的集合操作 与 stream集合操作
 **/
public class streamVs {
    /**
     * 1. 向看看购物侧都有什么商品
     * 2. 图书类都给买
     * 3.其余的商品中买两件最贵的。
     * 4.只需两件商品的名称和总价
     **/

    /**
     * 原始的方法
     **/
    @Test
    public void oldCartHandler(){
        List<Sku> cartSkuList = CartService.getCartSkuList();
        /**
         *1.查看所有图书
         **/
        for(Sku sku:cartSkuList){
            System.out.println(JSON.toJSONString(sku,true));
        }
        /**
         * 2.图书全部过滤掉
         **/
        List<Sku> notBooksSkuList = new ArrayList<>();
        for(Sku sku:cartSkuList){
            if(!sku.getSkuCategory().equals(SkuCategory.BOOK)){
                notBooksSkuList.add(sku);
            }
        }
        /**
         * 其余商品中买两件最贵的
         **/
        //注意排序方法，new Comparator，，和返回的是 1，-1，0
        // 排序
        notBooksSkuList.sort(new Comparator<Sku>() {
            @Override
            public int compare(Sku o1, Sku o2) {
                if(o1.getTotalPrice() > o2.getTotalPrice()){
                    return -1;
                }else if(o1.getTotalPrice() < o2.getTotalPrice()){
                    return 1;
                }else {
                    return 0;
                }

            }
        });
        List<Sku> top2SkuList = new ArrayList<>();
        for(int i = 0;i<2;i++){
            top2SkuList.add(notBooksSkuList.get(i));
        }

        /**
         * 4.求两件商品的总价
         **/
        Double money = 0.0;
        List<String> resultTop2List = new ArrayList<>();
        for(Sku sku:top2SkuList){
            money +=sku.getTotalPrice();
            resultTop2List.add(sku.getSkuName());
        }
        System.out.println("最高两件商品名称："+JSON.toJSONString(resultTop2List,true));
        System.out.println("最高两件商品总价："+money);

    }

    /**
     * stream流的方法
     **/
    public void newCartHandler(){
        //可以在lambda 中引用的变量,,在多线程中是安全的。
        AtomicReference<Double> money = new AtomicReference<>(Double.valueOf(0.0));


        List<String> collect = CartService.getCartSkuList()
                .stream()
                /**
                 * 1.打印所有商品信息，，，不要结束标志
                 **/
                .peek(i -> System.out.println(JSON.toJSONString(i, true)))
                /**
                 *
                 *2.过滤掉 属于 图书类 的数据，，filter 只会收录  {。。。。} 结果为true 的数据。
                 *  如果返回的是true 那么这个元素不会被过滤，为false 这个元素就会被过滤。
                 **/
                .filter(i -> !i.getSkuName().equals(SkuCategory.BOOK))
                /**
                 * 3.排序 ，默认的排序规则是从小到大
                 * Comparator.comparing(Sku::getTotalPrice) ；依据Sku::getTotalPrice排序，这里是方法引用、
                 **/
                .sorted(Comparator.comparing(Sku::getTotalPrice).reversed())
                /**
                 * 选择 top2  这里操作结束后返回的流 notBook，top2的流
                 **/
                .limit(2)
                /**
                 * 注意看 peek() 里面的参数是Consumer
                 * top2 商品的总价格 ==》 这里操作结束后 返回的流 还是 notBook，top2的流
                 **/
                .peek(sku -> {
                    money.set(money.get() + sku.getTotalPrice());
                })
                /**
                 * top2 商品的名字  ==》 但是操作结束以后返回的流就是 商品名字的流了，
                 **/
                .map(sku -> sku.getSkuName())
                /**
                 * 收集结果
                 * 收集齐 最终返回的 是这里toList() 后的结果。
                 **/
                .collect(Collectors.toList());

                System.out.println("top 2 商品名称列表:"+JSON.toJSONString(collect,true));
                System.out.println("商品总价："+money.get());
    }
}
